#!/bin/bash
###########################################################################
# This shell libarary gathers any useful tools to improve labor efficiency!
###########################################################################

#-----------------------------------------------------------
#                COLOUR VARIABLES
#-----------------------------------------------------------
UNDERLINE="\033[4m"
FG_BLACK="\033[30m"
FG_RED="\033[31m"
FG_GREEN="\033[32m"
FG_YELLOW="\033[33m"
FG_BLUE="\033[34m"
FG_PURPLE="\033[35m"
FG_DARKGREEN="\033[36m"
FG_WHITE="\033[37m"
BG_BLACK="\033[40m"
BG_RED="\033[41m"
BG_GREEN="\033[42m"
BG_YELLOW="\033[43m"
BG_BLUE="\033[44m"
BG_PURPLE="\033[45m"
BG_DARKGREEN="\033[46m"
BG_WHITE="\033[47m"
F6_END="\033[0m"

#-----------------------------------------------------------
#                SHELL TOOLS
#-----------------------------------------------------------

# Sync: synchronize cscope tags and ctags
function Sync()
{
	if [ "$1" = "b" ] || [ "$1" = "-b" ]; then
		find -L . -name "*.h" -o -name "*.c" -o -name "*.cpp" -o -name "*.lua" -o -name "*.def"> cscope.files
		cscope -bkq -i cscope.files
		ctags -R --links=yes --c++-kinds=+px --fields=+iaKSz --extras=+q .
		#ctags -R --links=yes
	elif [ "$1" = "c" ] || [ "$1" = "-c" ]; then
		rm -f cscope.files cscope.in.out cscope.out cscope.po.out tags
	else
		echo -e $FG_YELLOW
		echo -e "Usage: Sync [OPTION]"
		echo -e $FG_GREEN
		echo -e "\t-b       build the cross-reference"
		echo -e "\t-c       clear the cross-reference"
		echo -e $F6_END
	fi
}

#universal-ctags
#ctags --version to show version.
function ut()
{
    ctags -R --kinds-c++=+dfghmstuvcnz --fields-c++=+{template}{properties}{captures} --languages=c++ ---extras=+q -f tags .
}
# static: export project root path
function dir_export()
{
	case $# in
		1 )
			# export project root directory
			export PROJ_ROOT_PATH=$1
			# export project customer directory
			#eval $(grep "export CUSTOMER_FOLDER" $PROJ_ROOT_PATH/build.env)
			;;
		2 )
			if [ -d "$1" ]; then
				export PROJ_ROOT_PATH=$1
				#eval $(grep "export CUSTOMER_FOLDER" $PROJ_ROOT_PATH/build.env)

				# create a link 'cpe-build' to current project in place.
				ln -sfn $PROJ_ROOT_PATH $(dirname $PROJ_ROOT_PATH)/cpe-build
			fi
			;;
		* )
			;;
	esac

	echo -ne "$FG_DARKGREEN"
	echo -ne "$PROJ_ROOT_PATH"
	echo -e  "$F6_END"
}

# static: decide project path
function dir_decide()
{
	local GENERIC_PROJECT=cpe-build

	case $1 in
		"" )
			;;
		1 )
			dir_export ~/workspace/$GENERIC_PROJECT
			;;
		2 )
			dir_export ~/workroom/$GENERIC_PROJECT
			;;
		l |"lo" )
			dir_export $(get_proj_name)
			;;
		* )
			dir_export "$(dirname $PROJ_ROOT_PATH)/$1" "$(dirname $PROJ_ROOT_PATH)/$GENERIC_PROJECT"
			;;
	esac
}

#get current path's project name
function get_proj_name()
{
	local cur_dir=$(pwd)
	local tmp_path=$(dirname $PROJ_ROOT_PATH)
	if [[ "$cur_dir" =~ ${tmp_path}/.* ]];then
		cur_dir=${cur_dir#${tmp_path}/}
		cur_dir=$(echo $cur_dir | cut -d/ -f1)
		echo -n "${tmp_path}/${cur_dir}"
	fi

	return 0
}

# print or set project root path
function dir_set()
{
	if [ $# = 0 ]; then

		echo "Please choose main directory:"
		echo "  1: ~/workspace/cpe-build"
		echo "  2: ~/workroom/cpe-build"
		echo "Anykey other key to give up!!!"
		echo ""

		read -n 1 -p "which one: " op
		if [ "$op" == "" ]; then
			echo -ne "proj path:"
			echo -ne "$FG_DARKGREEN"
			echo -ne "$PROJ_ROOT_PATH"
			echo -e  "$F6_END"
		else
			echo -e "\nyou choosed the option-${FG_PURPLE}$op${F6_END}!\n";
			dir_decide "$op"
		fi

	else
		dir_decide "$@"
	fi
}

##################################################
# $1 - new dir
# $2 - old dir
##################################################
function try_cd()
{
	local _1_=$PROJ_ROOT_PATH/$1
	local _2_=$PROJ_ROOT_PATH/$2

	if [ -d "$_1_" ]; then
		echo -e $FG_YELLOW$(dirname $PROJ_ROOT_PATH)/$F6_END$BG_YELLOW$(basename $PROJ_ROOT_PATH)$F6_END$FG_YELLOW/$1$F6_END;cd $_1_
	elif [ -d "$_2_" ]; then
		echo -e $FG_YELLOW$(dirname $PROJ_ROOT_PATH)/$F6_END$BG_YELLOW$(basename $PROJ_ROOT_PATH)$F6_END$FG_YELLOW/$2$F6_END;cd $_2_
	else
		echo -ne "$FG_RED"
		echo -ne "No Such Dir!"
		echo -e  "$F6_END"
	fi
}

# change directory
function ch()
{
	if [ "$PROJ_ROOT_PATH" = "" ];then
		echo "Please give the main directory first!"
		return 0
	fi

	case $1 in
		- )
			cd -
			;;
		"" )
			try_cd
			;;
		b|boot )
			try_cd ../bootldr.rtl
			;;
		com )
			try_cd simulator/core/code/future/ISS/common
			;;
		u|ubuntu )
			cd ~/Documents/Weapons/ubuntu
			;;
		k3 )
			cd ~/kernel/linux-2.6
			;;
		* )
			cd "$1"
			;;
	esac

	return $?
}

#for cameo
function sw1()
{
	if [ "$PROJ_ROOT_PATH" = "" ];then
		echo "Please give the main directory first!"
		return 0
	fi

	case $1 in
		- )
			cd -
			;;
		"" )
			try_cd
			;;
		b|boot )
			try_cd boot/uboot_bcm_switch/uboot boot/uboot_rtk_switch/u-boot-2011.12
			;;
		k|kk )
			try_cd os/os_bcm_switch/kernel/linux-3.6.5 os/os_rtk_uClinux_switch/uClinux/linux-2.6.x
			;;
		a|arch )
			try_cd os/os_bcm_switch/kernel/linux-3.6.5/arch/arm/mach-iproc
			;;
		c|cus )
			try_cd core/code/customer/${CUSTOMER_FOLDER}
			;;
		w|www )
			try_cd core/code/customer/${CUSTOMER_FOLDER}/htmlpages
			;;
		n|np )
			try_cd core/code/customer/${CUSTOMER_FOLDER}/npapi
			;;
		f|fu )
			try_cd core/code/future
			;;
		ce|code )
			try_cd core/code/
			;;
		i|inc|include )
			try_cd core/code/future/inc
			;;
		is|iss|ISS|I )
			try_cd core/code/future/ISS
			;;
		co|common )
			try_cd core/code/future/ISS/common
			;;
		msr )
			try_cd core/code/future/ISS/common/msr
			;;
		l|lr )
			try_cd core/code/future/LR
			;;
		m|mib )
			try_cd core/code/future/mibs
			;;
		o|opensource)
			try_cd core/code/opensource
			;;
		rpc )
			try_cd core/code/future/ISS/common/cmrpc
			;;
		s|sdk )
			try_cd sdk/sdk_bcm_switch/sdk-xgs-robo sdk/sdk_rtk_switch/rtk-sdk
			;;
		r|rootfs )
			try_cd target/rootfs
			;;
		e|erps )
			try_cd core/code/future/erps
			;;
			# personal
			d )
			cd ~/deepin/
			;;
		* )
			cd "$1"
			;;
	esac

	return $?
}

#design for elite
function sw()
{
	if [ "$PROJ_ROOT_PATH" = "" ];then
		echo "Please give the main directory first!"
		return 0
	fi

	case $1 in
		- )
			cd -
			;;
		"" )
			try_cd
			;;
		doc )
			try_cd docs
			;;
		i|inc )
			try_cd include/modules
			;;
		sc|scr )
			try_cd scripts
			;;
		bd )
			try_cd build
			;;
		s|src )
			try_cd src
			;;
		m )
			try_cd src/modules
			;;
		cmn )
			try_cd src/modules/eli_common
			;;
		cmun )
			try_cd src/modules/eli_communication
			;;
		io )
			try_cd src/modules/eli_rbio
			;;
		mdb )
			try_cd src/modules/eli_modbus
			;;
		log )
			try_cd src/modules/eli_log
			;;
		p|py )
			try_cd src/modules/eli_python
			;;
		xd )
			try_cd build/x86/debug
			;;
		xr )
			try_cd build/x86/relwithdebinfo
			;;
		ad )
			try_cd build/arm/debug
			;;
		ar )
			try_cd build/arm/relwithdebinfo
			;;
		# personal
		d )
			cd ~/deepin/
			;;
		* )
			cd "$1"
			;;
	esac

	return $?
}


function p()
{
	if [ $# -eq "0" ]; then
		ping www.sohu.com
	else
		ping $*
	fi
}

function p6()
{
	ping6 $*
}

function f()
{
	if [ $# = 1 ]; then
		find `pwd` -name "$1"
	fi

	if [ $# = 2 ]; then
		find "$1" -name "$2"
	fi
}

function fr()
{
	if [ $# = 1 ]; then
		find `pwd` -regex "$1"
	fi

	if [ $# = 2 ]; then
		find "$1" -regex "$2"
	fi
}


function g()
{
	if [ $# = 1 ]; then
		grep -Irns --exclude=cscope.out --exclude=tags -- "$1" *
	fi

	if [ $# = 2 ]; then
		grep -Irns --exclude=cscope.out --exclude=tags -- "$1" "$2"
	fi
}

function gi()
{
	if [ $# = 1 ]; then
		grep -Iirns --exclude=cscope.out --exclude=tags -- "$1" *
	fi

	if [ $# = 2 ]; then
		grep -Iirns --exclude=cscope.out --exclude=tags -- "$1" "$2"
	fi
}


function a()
{
	# sudo apt-get install silversearcher-ag
	# install firstly
	# -U : Ignore VCS ignore files (.gitignore, .hgignore), but still use .ignore.
	# -p :Provide a path to a specific .ignore file.
	# -G : Only search files whose names match PATTERN.
	# -i : ignore case
	# -s : case senstive
	# --nogroup: every match would have it's filename added before
	# --silent: output exclude log message or error info
	# coulde be used : --hidden : search hidden file

	case $# in
		1 )
			ag  -sU  -p ~/.agignore --nogroup  --silent -- "$1"
			;;

		2 )
			ag  -sU  -p ~/.agignore  --nogroup  --silent -G "$2" -- "$1"
			;;

		* )
			ag -s "$@"
			;;
	esac
}

function ai()
{
	#ref: https://blog.csdn.net/weixin_33834910/article/details/93173918?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.channel_param&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.channel_param

	case $# in
		1 )
			ag  -iU  -p ~/.agignore --nogroup  --silent -- "$1"
			;;

		2 )
			ag  -iU  -p ~/.agignore --nogroup  --silent -G "$2" -- "$1"
			;;

		* )
			ag  -i "$@"
			;;
	esac
}

function clone()
{
	if [ -n "$1" ]; then
		git clone git@gitlab.elite-robot.org:e-project/elibot-control/EliServer.git  "$1"
	else
		git clone git@gitlab.elite-robot.org:e-project/elibot-control/EliServer.git
	fi
}

function mystart()
{
    synergy &
}

function vv()
{
	if [ $# -eq 1 ]; then
		if [ -n "$1" ]; then
			echo "$1"
			cur_dir=$1
			cur_dir=${cur_dir/:/\ +}
			if [ "$1" = "${cur_dir}" ]; then
				vi $1
			else
				vi ${cur_dir}
			fi
		else
			echo "error path"
		fi
	elif [ $# -eq 2 ]; then
		vi "$@"
	fi
}

#useage : a2l <address>
function a2l()
{
	/opt/toolchain/mips-linux-uclibc/usr/bin/mips-linux-addr2line -Cfse \
		$PROJ_ROOT_PATH/core/code/future/LR/ISS.exe  "$1"
}

# for bcm teg-30284
function b_a2l()
{
	/opt/toolchain/iProcLDK_3.6.2/usr/bin/arm-broadcom-linux-uclibcgnueabi-addr2line -Cfse \
		$PROJ_ROOT_PATH/core/code/future/LR/ISS.exe "$1"
}

function a2fun()
{
	if [ ! $# -eq 1 ];then
		echo "Usage : $0 <dumpfilename>"
		return 0
	fi

	if [ ! -e "$1" ];then
		echo "could not found file :$1"
		return 0
	fi

	local dump_dir=$PROJ_ROOT_PATH/host/utility/dump
	cd $dump_dir
	cat "$1" >  $dump_dir/1.log
	$dump_dir/addr2fun.sh  /opt/toolchain/mips-linux-uclibc/usr/bin/mips-linux-objdump -f  $dump_dir/1.log
	cat $dump_dir/1.log_parse.log > "$dump_dir/$(basename "$1").parsed"
	echo -e "The result file is \n\t$FG_RED $dump_dir/$(basename "$1").parsed $F6_END"

}

function b_a2fun()
{
	if [ ! $# -eq 1 ];then
		echo "Usage : $0 <dumpfilename>"
		return 0
	fi

	if [ ! -e "$1" ];then
		echo "could not found file :$1"
		return 0
	fi

	local dump_dir=$PROJ_ROOT_PATH/utility/dump
	cd $dump_dir
	cat "$1" >  $dump_dir/1.log
	$dump_dir/addr2fun.sh  /opt/toolchain/iProcLDK_3.6.2/usr/bin/arm-linux-objdump -f  $dump_dir/1.log
	cat $dump_dir/1.log_parse.log > "$dump_dir/$(basename "$1").parsed"
	echo -e "The result file is \n\t$FG_RED $dump_dir/$(basename "$1").parsed $F6_END"

}

function dmp()
{
	local dump_range="10"
	if [ $# -eq 0 -o $# -gt 2 ];then
		echo "Usage: $0 <dump address> [range]"
		return 0
	elif [ $# -eq 2 ];then
		dump_range="$2"
		echo "         dump_range = $dump_range"
	fi

	echo -e "The 1st param :\t\t$(printf %#x 0x$1)"
	/opt/toolchain/iProcLDK_3.6.2/usr/bin/arm-linux-objdump -dS \
		$PROJ_ROOT_PATH/core/code/future/LR/ISS.exe \
		"--start-address="$(printf %#x $((0x$1 - $dump_range))) \
		"--stop-address="$(printf %#x $((0x$1 + $dump_range)))

}
function cc()
{
	local cur=$(pwd)

	# test the current path whether in the project directory
	pwd | grep -E "$(dirname $PROJ_ROOT_PATH)/" >/dev/null
	if [ $? -ne 0 ];then
		echo  Please give a validate dir !!
		return 0
	else
		cur=${cur#$(dirname $PROJ_ROOT_PATH)} #cur will be like "/trendnet"
		echo "---debug----cur= $cur"
		if [ $cur == "" ];then
			echo  Please give a valid dir !!
			return 0
		else
			cur=$(dirname $PROJ_ROOT_PATH)/$(echo $cur | cut -d/ -f2)  # -f2, because the cut thing like "/project/"

			#now cur turn to  "/home/hehe/workspace/PROJ"
			echo "---debug----cur= $cur"
			if [ ! -d "$cur" ];then
				echo  Please give a validate dir !!
				return 0
			fi
		fi
	fi

	# clean the current project's image dir.
	if [ -e ${cur}/image/squashfs.vc ];then
		local tmp_time=$(ls -l ${cur}/image/squashfs.vc | cut -d' ' -f6-8)
		#tmp_time now like "Sep 16 14:18"
		tmp_time=_${tmp_time// /_}
		#tmp_time now like "_Sep_16_14:18"

		rm -f ${cur}/image/squashfs.vc_*
		mv "${cur}/image/squashfs.vc"  "${cur}/image/squashfs.vc${tmp_time}"

		rm -f ${cur}/image/squashfs.vc
	fi

	case $# in
		0 )
			echo "execute make sfw"
			make -C "$cur" sfw
			;;

		* )
			case $1 in
				1 )
					echo "execute make core fw.all"
					make -C "$cur" core fw.all
					;;
				2 )
					echo "execute make core-clean core fw.all"
					make -C "$cur" core-clean core fw.all
					;;
				* )
					echo "make -C "$cur" "$@""
					make -C "$cur" "$@"
					;;
			esac
			;;
	esac

	#Compile finished,check whether successful
	if [ -f ${cur}/image/squashfs.vc ];then
		cp ${cur}/image/squashfs.vc  /mnt/hgfs/Z
		if [ $? -eq 0 ];then
			notify-send "Successfully compiled with copied !"
		else
			echo -e "\033[31;47m Copy to tftp dir failed ! \033[0m"
			notify-send "Copy to TFTP file failed !"
		fi

	else
		notify-send "Compile failed !, Please check your CMD!"
	fi
}
# used to colour matching
function pc()
{
	echo "print color:"
	for i in {0..255} ; do
		printf "\x1b[48;5;%sm%3d\e[0m " "$i" "$i"
		if (( i == 15 )) || (( i > 15 )) && (( (i-15) % 6 == 0 )); then
			printf "\n";
		fi
	done
}

#count the length of chars
function cnt()
{
	echo "The length of given string is: "
	echo -n "$@" | wc -c
}


#share clipboard through internet
function shar()
{
    echo -e "\t\tPlease type in what you want share, and end with <C-D>\n"
    curl -F 'f:1=<-' ix.io
}

pdf()
{
    cp -af `find . -path "./qwert" -prune -o  -name "*.pdf" -print | sed -e 's,\(.*/\).*,\1\*.pdf,g'` pdf
}

# used on specified files copy
# $1 --> regular expression   $2 --> dst path of cp
regcp()
{
    find  ./ -regex "$1" -exec cp -n "{}" "$2" \;
}

#elite build shell
function bd()
{
	local arg_1
	local local_path=$(get_proj_name)
	case $# in
		0 )
			echo "excute ${local_path}/scripts/build.sh x86 debug "
			${local_path}/scripts/build.sh x86 debug
			#./scripts/build.sh x86 debug
			;;

		1 | 2 )
			if [ "$1" -eq 1 ]; then
				#./scripts/build.sh x86 debug
				arg_1="x86"
			elif [ "$1" -eq 2 ]; then
				#./scripts/build.sh arm debug
				arg_1="arm"
			else
				echo "please give specific number:"
				echo "      1: x86 debug"
				echo "      2: arm debug"
			fi

			if [ "$2" != '' ];then
				case "$2" in
					"c"|"clean")
						${local_path}/scripts/clean.sh "$arg_1" debug
						;;
					*)
						${local_path}/scripts/build.sh "$arg_1" "$2"
						;;
				esac

			else
				${local_path}/scripts/build.sh "$arg_1" debug
			fi
			;;

			*)
			echo "UNKNOW command: bd $@ "
			;;
	esac
}

#elite excute bin
function db()
{
	local local_path=$(get_proj_name)
	local arg_1

	case $# in
		0 )
			echo "excute ${local_path}/build/x86/debug/bin/start_eliserver.sh "
			cd ${local_path}/build/x86/debug/bin/ ; \
				./start_eliserver.sh ; cd -
			;;

		1 | 2 )
			case "$1" in
				1 )
					arg_1="debug"
				;;

				2 )
					arg_1="relwithdebinfo"
				;;

				t | stop)
					${local_path}/build/x86/debug/bin/stop_eliserver.sh
					if [ $? -eq 0 ]; then
						echo -e ${FG_PURPLE}  "\t\tStop EliServer successfully ! " ${F6_END} "\n"
						notify-send "Stop EliServer successfully !"
					fi
					return
				;;

				*)
				echo "please give specific char: db <arg1> <arg2>"
				echo "      1: debug "
				echo "      2: relwithdebinfo "
				echo "      t: stop EliServer "

				return
			esac

			case "$2" in
				s | start | '' )
					cd ${local_path}/build/x86/${arg_1}/bin/ ; \
						./start_eliserver.sh ; cd - ;
				;;
				* )
					echo "UNKNOW command: db $@ "
				;;
			esac
			;;

		*)
			echo "UNKNOW command: db $@ "
			;;
	esac
}

chgcc()
{
    local gcc_file=/usr/bin/gcc-"$1"
    if [ -f "${gcc_file}" ];then
        sudo ln -sf /usr/bin/gcc-"$1" /usr/bin/gcc
        sudo ln -sf /usr/bin/gcc-ar-"$1" /usr/bin/gcc-ar
        sudo ln -sf /usr/bin/gcc-nm-"$1" /usr/bin/gcc-nm
        sudo ln -sf /usr/bin/gcc-ranlib-"$1" /usr/bin/gcc-ranlib
    else
        echo  "No $gcc_file file ! Please check."
    fi

    local gxx_file=/usr/bin/g++-"$1"
    if [ -f "${gxx_file}" ];then
        sudo ln -sf /usr/bin/g++-"$1" /usr/bin/g++
    else
        echo  "No $gxx_file file ! Please check."
    fi
}
function mygcc()
{
    if [[ $# -eq 1 ]]; then
        cur_file=$1
        # echo "$cur_file"
        # cur=${cur_file%*${cur_file:(-2)}}
        # echo "$cur"
        # cur1=${cur_file/.c/}
        # echo "$cur1"
        gcc $1 -o ${cur_file/.c/}
    else
        echo "error, for example : mygcc 1.c"
    fi
}
function myg++()
{
    if [[ $# -eq 1 ]]; then
        cur_file=$1
        g++ $1 -o ${cur_file/.cpp/}
    else
        echo "error, for example : mygcc 1.c"
    fi
}


